home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / cmdity / yk212src.lha / Yak_2.12_Src / WBStartup / DigitalClock.c < prev    next >
C/C++ Source or Header  |  1996-02-07  |  24KB  |  989 lines

  1. /*
  2.  **  Module: DigitalClock (DC)
  3.  **
  4.  **  Purpose: displays up a digital clock in the top right corner
  5.  **  of title bar screen
  6.  **
  7.  **  Largely inspired from Anders Hammarquist TitleClock source
  8.  **
  9.  */
  10. #define DEBUG
  11.  
  12. #include <dos/datetime.h>
  13. #include <dos/dos.h>
  14. #include <exec/memory.h>
  15. #include <exec/execbase.h>
  16. #include <exec/devices.h>
  17. #include <exec/libraries.h>
  18. #include <intuition/intuition.h>
  19. #include <intuition/intuitionbase.h>
  20. #include <graphics/gfx.h>
  21. #include <libraries/commodities.h>
  22. #include <libraries/iffparse.h>
  23. #include <libraries/locale.h>
  24. #include <devices/timer.h>
  25.  
  26. #include <proto/exec.h>
  27. #include <proto/dos.h>
  28. #include <proto/graphics.h>
  29. #include <proto/intuition.h>
  30. #include <proto/icon.h>
  31. #include <proto/iffparse.h>
  32. #include <proto/utility.h>
  33. #include <proto/commodities.h>
  34. #include <proto/timer.h>
  35. #include <proto/locale.h>
  36. #include <workbench/workbench.h>
  37. #include <workbench/startup.h>
  38. #include <string.h>
  39.  
  40. #include "yak.h"
  41. #include "code.h"
  42. #include "DigitalClock.h"
  43. #include "GetScreenBox.h"
  44. #include "settings.h"
  45. #include "Hotkey_types.h"
  46.  
  47. #ifdef STAND_ALONE
  48. struct Locale   *locale;
  49. #else
  50. # define CATCOMP_BLOCK
  51. # define CATCOMP_NUMBERS
  52. # include "yak_locale_strings.h"
  53. #endif
  54.  
  55. /* Maximum length of text displayed in clock */
  56. #define DC_C0_MAXCLOCKLEN 50
  57.  
  58. /* From sysiclass docs */
  59. #define DC_C0_LOWDEPTHWIDTH 17
  60. #define DC_C0_HIDEPTHWIDTH  23
  61.  
  62. static struct RastPort    *DC_V0_RPort = NULL;
  63. static struct BitMap      *DC_V0_BitMap = NULL;
  64. static struct TextFont    *DC_V0_TitleFont;
  65. static struct TextFont    *DC_V0_Old_TitleFont;
  66. static struct Screen      *DC_V0_Old_Scr;
  67. static int                 DC_V0_BltLen;
  68. static int                 DC_V0_Old_BltLen;
  69. static int                 DC_V0_LeftEdge;
  70. static int                 DC_V0_Old_LeftEdge;
  71. static UWORD               DC_V0_FrontPen;
  72. static UWORD               DC_V0_BackPen;
  73. static UWORD               DC_V0_Old_BackPen;
  74. static struct timerequest *DC_V0_TimerIO = NULL;
  75. static struct MsgPort     *DC_V0_TimerPort = NULL;
  76.  
  77.  
  78. ULONG DC_V_TimerSig;
  79.  
  80. struct Library *TimerBase;
  81.  
  82. /* Default configuration of the clock */
  83.  
  84. const DC_T_Config DC_C0_Config_Def =
  85. {
  86.    DC_C_UNACTIVE,
  87.    5,
  88.    1,
  89.    FALSE,
  90.    FALSE,
  91.    FALSE,
  92.    FALSE,
  93.    DC_C_FormatDos,
  94.    NULL,
  95.    DC_C_FrontPubScreen,
  96. {"#?", NULL},
  97.    FALSE
  98. };
  99.  
  100. /* Current configuration of the clock */
  101.  
  102. DC_T_Config DC_V_Config;
  103.  
  104. /* Indicates whether or not the clock has been initialized */
  105.  
  106. BOOL DC_V0_Initialized = FALSE;
  107.  
  108. #if !defined(PREFS) && !defined(CONV)
  109.  
  110.  
  111. /* Function prototypes */
  112.  
  113. static void DC_F0_DisplayOnSelectedScreen (char *, unsigned int );
  114.  
  115. static void DC_F0_DisplayClk(char *, unsigned int, struct Screen * );
  116.  
  117. static void DC_F0_DeleteClk(void);
  118.  
  119. static void DC_F0_UpdateClk(void);
  120.  
  121. static void
  122.    DC_F0_AbortTimer(void)
  123. {
  124.    if (DC_V_Config.TimerRunning == TRUE)
  125.    {
  126.       /* Abort timer request */
  127.       
  128.       AbortIO(&DC_V0_TimerIO->tr_node);
  129.       WaitIO(&DC_V0_TimerIO->tr_node);
  130.       
  131.       DC_V_Config.TimerRunning = FALSE;
  132.    }
  133. }
  134.  
  135.  
  136. void 
  137.    DC_F_CleanUp(void)
  138. {
  139.    DC_F0_AbortTimer();
  140.    
  141.    DC_F0_DeleteClk();
  142.    
  143.    if (DC_V0_BitMap)
  144.    {
  145.       FreeVec(DC_V0_BitMap->Planes[0]);
  146.       FreeVec(DC_V0_BitMap);
  147.    }
  148.    
  149.    FreeVec(DC_V0_RPort);
  150.    
  151.    FreeVec(DC_V_Config.LocaleDateFormat);
  152.    
  153.    FreeVec(DC_V_Config.ScreenPatternData.pat);
  154.    
  155.    /* Timer stuff */
  156.    
  157.    if (DC_V0_TimerIO) 
  158.    {
  159.       CloseDevice(DC_V0_TimerIO);
  160.       DeleteIORequest(&DC_V0_TimerIO->tr_node);
  161.    }
  162.    
  163.    if (DC_V0_TimerPort) 
  164.       DeleteMsgPort(DC_V0_TimerPort);
  165.    
  166.    TimerBase = (struct Library *)(-1);
  167. }
  168.  
  169. void
  170.    DC_F_DisableClock(void)
  171. {
  172.    DC_F0_AbortTimer();
  173.    DC_F0_DeleteClk();
  174. }
  175.  
  176.  
  177. void
  178.    DC_F_EnableClock(void)
  179. {
  180.    DC_F0_AbortTimer();
  181.    DC_F0_UpdateClk();
  182. }
  183.  
  184. /*
  185.  * Init DigitalClock module
  186.  */ 
  187.  
  188. int
  189.    DC_F_Init(void)
  190. {
  191.    if (DC_V0_Initialized == FALSE)
  192.    {
  193.       if (!(DC_V0_TimerPort = CreateMsgPort()))
  194.       {
  195.          return 1;
  196.       }
  197.  
  198.       if (DC_V_TimerSig == 0)
  199.       {
  200.          DC_V_TimerSig = 1 << DC_V0_TimerPort->mp_SigBit;
  201.       }
  202.  
  203.       if (!(DC_V0_TimerIO = (struct timerequest *) 
  204.             CreateIORequest(DC_V0_TimerPort, sizeof(struct timerequest))))
  205.       {
  206.          return 1;
  207.       }
  208.       
  209.       /* Open timer.device */
  210.       if (OpenDevice(TIMERNAME, UNIT_WAITUNTIL, &DC_V0_TimerIO->tr_node, 0))
  211.       {
  212.          return 1;
  213.       }
  214.       
  215.       /* Library pointer */
  216.       TimerBase = (struct Library *)DC_V0_TimerIO->tr_node.io_Device;
  217.       
  218.       /* Init timerequest */
  219.       DC_V0_TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  220.       DC_V0_TimerIO->tr_time.tv_micro = 0;
  221.       
  222.       
  223.       /* Initialize Screen Pattern */
  224.       if (DC_V_Config.ScreenSelection == DC_C_ScreensByPattern)
  225.       {
  226.          InitPattern(NULL, &DC_V_Config.ScreenPatternData);
  227.       }
  228.       
  229.       /* Allocate BitMap and RastPort */
  230.       DC_V0_BitMap = AllocVec(sizeof(struct BitMap), MEMF_CLEAR|MEMF_PUBLIC);
  231.       DC_V0_RPort  = AllocVec(sizeof(struct RastPort),MEMF_CLEAR|MEMF_PUBLIC);
  232.       
  233.       if (DC_V0_BitMap && DC_V0_RPort)
  234.       {
  235.          InitRastPort(DC_V0_RPort);
  236.          DC_V0_RPort->BitMap = DC_V0_BitMap;
  237.       }
  238.       else 
  239.       {
  240.          DC_V0_Initialized = FALSE;
  241.          return 1;
  242.       }
  243.       DC_V0_Initialized = TRUE;
  244.    }
  245.    
  246.    if (DC_V_Config.State == DC_C_ACTIVE)
  247.    {
  248.       RegisterSignal(DC_V_TimerSig);
  249.       DC_F_EnableClock();
  250.    }     
  251.    else
  252.    {
  253.       DC_F_DisableClock();
  254.    }
  255.    
  256.    return 0;
  257. }    
  258.  
  259.  
  260. void
  261.    DC_F_ProcessMsg(
  262.                    long sig)
  263. {
  264.    if (sig & DC_V_TimerSig)
  265.    {
  266.       while (GetMsg(DC_V0_TimerPort))
  267.       {
  268.          if (DC_V_Config.TimerRunning == TRUE)
  269.             DC_F0_UpdateClk();
  270.       }
  271.    }       
  272. }
  273.  
  274.  
  275.  
  276. void ASM
  277.    SPFunc( 
  278.           REG(a0) struct Hook *pHook,
  279.           REG(a1) char pChar)
  280. {
  281.    /* Quick-and-dirty isprint() +
  282.     * make sure that we're not 
  283.     * printing too many chars. 
  284.     */
  285.    
  286.    if ((pChar&0x60) && 
  287.        ((int)pHook->h_Data - (int)pHook->h_SubEntry < DC_C0_MAXCLOCKLEN)) 
  288.       *((*(char **)&(pHook->h_Data))++) = pChar;
  289. }
  290.  
  291. /* Print hook */
  292. struct Hook DC_V0_PrintHook =
  293. {
  294.    NULL, NULL,             /* MinNode */
  295.    (ULONG (* )())SPFunc,   /* h_Entry, PrintFunc */
  296.    NULL,                   /* h_SubEntry. Dirtily used as pointer for */
  297.    /* where the string began. */
  298.    NULL                    /* h_Data, where to put char */
  299.    };
  300.  
  301.  
  302.  
  303. /* print date */
  304. int 
  305.    SPrintD(
  306.            char             *I_Dest, 
  307.            char             *I_Fmt, 
  308.            struct DateStamp *I_Date)
  309. {
  310.    DC_V0_PrintHook.h_SubEntry = (ULONG (* )())(DC_V0_PrintHook.h_Data = I_Dest);
  311.    FormatDate(locale, I_Fmt, I_Date, &DC_V0_PrintHook);
  312.    *((char *)DC_V0_PrintHook.h_Data) = '\0';
  313.    
  314.    return ((int)((char *)DC_V0_PrintHook.h_Data - I_Dest)); /* return length of string */
  315. }
  316.  
  317. /* Delete previous clock */
  318.  
  319. static void 
  320.    DC_F0_DeleteClk(void)
  321. {
  322.    if (DC_V0_Old_Scr && DC_V0_Old_Scr->BarLayer &&
  323.        AttemptLockLayerRom(DC_V0_Old_Scr->BarLayer))
  324.    {
  325.       /* Empty RastPort */
  326.       
  327.       SetRast(DC_V0_RPort, DC_V0_Old_BackPen);
  328.       
  329.       ClipBlit(DC_V0_RPort, 0, 0, DC_V0_Old_Scr->BarLayer->rp, DC_V0_Old_LeftEdge, 1, DC_V0_Old_BltLen, DC_V0_Old_TitleFont->tf_YSize, 0x0C0);
  330.       
  331.       UnlockLayerRom(DC_V0_Old_Scr->BarLayer);
  332.    }
  333. }
  334.  
  335.  
  336. /* Display clock on appropriate screen */
  337. static void 
  338.    DC_F0_DisplayClk(
  339.                    char *clkstr, 
  340.                    unsigned int clklen, 
  341.                    struct Screen *Scr)
  342. {
  343.    struct IBox box;
  344.    
  345.    if (Scr->BarLayer && AttemptLockLayerRom(Scr->BarLayer))
  346.    {
  347.       struct DrawInfo *dri;
  348.       int i;
  349.       WORD dSize;
  350.       
  351.       DC_V0_TitleFont = Scr->BarLayer->rp->Font; /* No need to 'open' it */
  352.       
  353.       if ((DC_V0_BitMap->Depth < MIN(Scr->RastPort.BitMap->Depth, 8)) ||
  354.           (DC_V0_BitMap->Rows < DC_V0_TitleFont->tf_YSize) ||
  355.           (DC_V0_BitMap->BytesPerRow < Scr->RastPort.BitMap->BytesPerRow))
  356.       {
  357.          /* Need 'better' rastport */
  358.          
  359.          FreeVec(DC_V0_BitMap->Planes[0]);
  360.          
  361.          InitBitMap(DC_V0_BitMap, 
  362.                     MAX(DC_V0_BitMap->Depth, MIN(Scr->RastPort.BitMap->Depth,8)),
  363.                     Scr->Width,
  364.                     MAX(DC_V0_BitMap->Rows, DC_V0_TitleFont->tf_YSize));
  365.          
  366.          if (!(DC_V0_BitMap->Planes[0] = AllocVec(DC_V0_BitMap->BytesPerRow*DC_V0_BitMap->Rows*DC_V0_BitMap->Depth, MEMF_CHIP)))
  367.          {
  368.             DC_V0_BitMap->Depth = 0;
  369.             goto next;
  370.          }
  371.          
  372.          for (i = 1; i < MIN(DC_V0_BitMap->Depth,8); i++)
  373.          {
  374.             DC_V0_BitMap->Planes[i] = ((UBYTE *)DC_V0_BitMap->Planes[i-1]) 
  375.                + DC_V0_BitMap->BytesPerRow*DC_V0_BitMap->Rows;
  376.          }
  377.       }
  378.       
  379.       if (dri = GetScreenDrawInfo(Scr))
  380.       {
  381.          if (dri->dri_NumPens >= 0x000A)
  382.          {
  383.             DC_V0_FrontPen = dri->dri_Pens[BARDETAILPEN];
  384.             DC_V0_BackPen = dri->dri_Pens[BARBLOCKPEN];
  385.          }
  386.          else
  387.          {
  388.             DC_V0_FrontPen = dri->dri_Pens[DETAILPEN];
  389.             DC_V0_BackPen = dri->dri_Pens[BLOCKPEN];
  390.          }
  391.          FreeScreenDrawInfo(Scr,dri);
  392.       }
  393.       /* If we don't get DrawInfo, the pens will be somewhat random */
  394.       
  395.       SetFont(DC_V0_RPort, DC_V0_TitleFont);
  396.       SetDrMd(DC_V0_RPort, JAM2);
  397.       SetAPen(DC_V0_RPort, DC_V0_FrontPen);
  398.       SetBPen(DC_V0_RPort, DC_V0_BackPen);
  399.       SetRast(DC_V0_RPort, DC_V0_BackPen);
  400.       
  401.       Move(DC_V0_RPort, DC_V0_TitleFont->tf_XSize, DC_V0_TitleFont->tf_Baseline);
  402.       
  403.       Text(DC_V0_RPort, clkstr, clklen);
  404.       
  405.       dSize = (Scr->Flags & SCREENHIRES?DC_C0_HIDEPTHWIDTH:DC_C0_LOWDEPTHWIDTH);
  406.       
  407.       DC_V0_BltLen = DC_V0_RPort->cp_x + DC_V_Config.Offset;
  408.       
  409.       GetScreenBox(Scr, &box, FALSE);
  410.       DC_V0_LeftEdge = MIN(Scr->Width - dSize, box.Left + box.Width);
  411.       
  412.       DC_V0_LeftEdge -= DC_V0_BltLen;
  413.       
  414.       /* If we have change screen since last update, remove clock from old screen
  415.        * as it won't be updated anymore.
  416.        * Same thing, if our clock has moved due to auto-scroll screens.
  417.        */
  418.       if ((Scr != DC_V0_Old_Scr) ||
  419.           (DC_V0_Old_LeftEdge != DC_V0_LeftEdge))
  420.       {
  421.          DC_F0_DeleteClk();
  422.       }
  423.       
  424.       ClipBlit(DC_V0_RPort, 0, 0, Scr->BarLayer->rp, DC_V0_LeftEdge, 1, DC_V0_BltLen, DC_V0_TitleFont->tf_YSize, 0x0C0);
  425.    next:
  426.       UnlockLayerRom(Scr->BarLayer);
  427.    }
  428. }
  429.  
  430.  
  431.  
  432. static void 
  433.    DC_F0_DisplayOnSelectedScreen (
  434.                                   char *DispStr, 
  435.                                   unsigned int StringLen)
  436. {
  437.    ULONG ILock;
  438.    struct Screen *Scr;
  439.  
  440.    /* This is part while the IntuitionBase lock is held not-quite
  441.     * legal. The AutoDoc says not to call any intuition,
  442.     * graphics, etc functions while holding the lock, but it
  443.     * seems to work. My guess is that the warning in the AutoDoc
  444.     * is to keep people from locking up the machine trying to
  445.     * draw while someone has a layer locked. If this is the
  446.     * reason, then the following should not cause any problems
  447.     * what so ever, since I won't draw unless I get to lock the
  448.     * layer. If there is some other obscure reason, then this may
  449.     * cause problems on some systems. But so far I haven't seen
  450.     * or heard of any problems with it, and it's really the only 
  451.     * way to do what we want to do. 
  452.     */ 
  453.    
  454.    ILock = LockIBase(0);
  455.    
  456.    switch (DC_V_Config.ScreenSelection)
  457.    {
  458.       
  459.    case DC_C_WorkbenchScreen:
  460.       if (Scr = LockPubScreen("Workbench"))
  461.       {
  462.          DC_F0_DisplayClk(DispStr, StringLen, Scr);
  463.          UnlockPubScreen(NULL,Scr);
  464.       }
  465.       break;
  466.       
  467.    case DC_C_FrontScreen:
  468.       Scr = IntuitionBase->FirstScreen;
  469.       if (Scr != NULL)
  470.       {
  471.          DC_F0_DisplayClk(DispStr, StringLen, Scr);
  472.       }
  473.       break;
  474.       
  475.    case DC_C_FrontPubScreen:
  476.       Scr = IntuitionBase->FirstScreen;
  477.       if ((Scr != NULL) &&
  478.           ((Scr->Flags & SCREENTYPE) != CUSTOMSCREEN))
  479.       {
  480.          DC_F0_DisplayClk(DispStr, StringLen, Scr);
  481.       }
  482.       else
  483.       {
  484.          /* If new screen doesn't apply, update old one */
  485.          if ((DC_V0_Old_Scr != NULL) &&
  486.              ((DC_V0_Old_Scr->Flags & SCREENTYPE) != CUSTOMSCREEN))
  487.          {
  488.             Scr = DC_V0_Old_Scr;
  489.             DC_F0_DisplayClk(DispStr, StringLen, Scr);
  490.          }
  491.          else
  492.          {
  493.             Scr = NULL;
  494.          }
  495.       }
  496.       break;
  497.       
  498.    case DC_C_DefPubScreen:
  499.       if (Scr = LockPubScreen(NULL))
  500.       {
  501.          DC_F0_DisplayClk(DispStr, StringLen, Scr);
  502.          UnlockPubScreen(NULL, Scr);
  503.       }
  504.       break;
  505.       
  506.    case DC_C_ScreensByPattern:
  507.       Scr = IntuitionBase->FirstScreen;
  508.       if ((Scr != NULL) && 
  509.           DC_V_Config.ScreenPatternData.patstr &&
  510.           Scr->DefaultTitle && 
  511.           MatchPattern(DC_V_Config.ScreenPatternData.pat, Scr->DefaultTitle))
  512.       {
  513.          DC_F0_DisplayClk(DispStr, StringLen, Scr);
  514.       }
  515.       else
  516.       {
  517.          /* If new screen doesn't apply, update old one */
  518.          if ((DC_V0_Old_Scr != NULL) &&
  519.              DC_V_Config.ScreenPatternData.patstr &&
  520.              DC_V0_Old_Scr->DefaultTitle && 
  521.              MatchPattern(DC_V_Config.ScreenPatternData.pat, DC_V0_Old_Scr->DefaultTitle))
  522.          {
  523.             Scr = DC_V0_Old_Scr;
  524.             DC_F0_DisplayClk(DispStr, StringLen, Scr);
  525.          }
  526.          else
  527.          {
  528.             Scr = NULL;
  529.          }
  530.       }
  531.       break;
  532.    }
  533.    UnlockIBase(ILock);
  534.  
  535.    if (Scr != NULL)
  536.    {
  537.       DC_V0_Old_Scr = Scr;
  538.    }
  539. }
  540.  
  541. /* Update clock */
  542. static void 
  543.    DC_F0_UpdateClk(void)
  544. {
  545.    struct DateTime dt;
  546.    char DispStr[DC_C0_MAXCLOCKLEN];
  547.    unsigned int V_StringLen;
  548.    
  549.    /* Save parameters of last display */
  550.  
  551.    DC_V0_Old_LeftEdge = DC_V0_LeftEdge;
  552.    DC_V0_Old_BltLen = DC_V0_BltLen;
  553.    DC_V0_Old_BackPen = DC_V0_BackPen;
  554.    DC_V0_Old_TitleFont = DC_V0_TitleFont;
  555.  
  556.    DispStr[0] = '\0';
  557.  
  558.    DateStamp(&dt.dat_Stamp);
  559.    
  560.    if ((DC_V_Config.DateFormat != DC_C_LocaleDateFormat) || 
  561.        (LocaleBase == NULL))
  562.    {
  563.       char StrDay[20];
  564.       char StrDate[20];
  565.       char StrTime[20];
  566.       int  len;
  567.  
  568.       dt.dat_Format = (UBYTE)DC_V_Config.DateFormat;
  569.       dt.dat_Flags  = 0;
  570.       if (DC_V_Config.ShowDay == TRUE)
  571.       {
  572.          dt.dat_StrDay = StrDay;
  573.       }
  574.       else
  575.       {
  576.          dt.dat_StrDay = NULL;
  577.       }
  578.       if (DC_V_Config.ShowDate == TRUE)
  579.       {
  580.          dt.dat_StrDate = StrDate;
  581.       }
  582.       else
  583.       {
  584.          dt.dat_StrDate = NULL;
  585.       }
  586.       dt.dat_StrTime = StrTime;
  587.       
  588.       DateToStr(&dt);
  589.  
  590.       if (DC_V_Config.ShowDay == TRUE)
  591.       {
  592.          if (DC_V_Config.ShortDay == TRUE) 
  593.          {
  594.             StrDay[3] = ' ';
  595.             StrDay[4] = '\0';
  596.          }
  597.          else
  598.          {
  599.             len = strlen(StrDay);
  600.             StrDay[len] = ' ';
  601.             StrDay[len + 1] = '\0';
  602.          }
  603.          strcat(DispStr, StrDay);
  604.       }
  605.       if (DC_V_Config.ShowDate == TRUE)
  606.       {
  607.          len = strlen(StrDate);
  608.          StrDate[len] = ' ';
  609.          StrDate[len + 1] = '\0';
  610.          strcat(DispStr, StrDate);
  611.       }
  612.       if (DC_V_Config.ShowSecs == FALSE)
  613.       {
  614.          len = strlen(StrTime);
  615.          StrTime[len - 3] = '\0';
  616.       }
  617.       strcat(DispStr, StrTime);
  618.  
  619.       V_StringLen = strlen(DispStr);
  620.       
  621.    }
  622.    else
  623.    {
  624.       /* Use Locale Format Date */
  625.       V_StringLen = SPrintD(DispStr, DC_V_Config.LocaleDateFormat, &dt.dat_Stamp);
  626.       
  627.    }
  628.  
  629.    /* Now display the things on the right screen */
  630.    DC_F0_DisplayOnSelectedScreen(DispStr, V_StringLen);
  631.    
  632.    /* reschedule timer */
  633.    GetSysTime(&DC_V0_TimerIO->tr_time);
  634.    
  635.    DC_V0_TimerIO->tr_time.tv_secs += DC_V_Config.Interval;
  636.    DC_V0_TimerIO->tr_time.tv_micro = 0;
  637.    SendIO(&DC_V0_TimerIO->tr_node);
  638.    DC_V_Config.TimerRunning = TRUE;
  639. }
  640. #endif /* not CONV and not PREFS */
  641.  
  642. void 
  643.    DC_F_Set_Default(void)
  644. {
  645.    memmove((void *)&DC_V_Config, (void const *)&DC_C0_Config_Def, sizeof(DC_T_Config)); 
  646. }
  647.  
  648. #ifndef CONV
  649.  
  650. /* YKDC chunk format
  651.  *
  652.  *      UWORD NUM_HANDLERS
  653.  *        UWORD  DC_V_Config.State
  654.  *        UWORD  DC_V_Config.Offset
  655.  *        LONG   DC_V_Config.Interval
  656.  *        BOOL   DC_V_Config.ShowDate
  657.  *        BOOL   DC_V_Config.ShowDay
  658.  *        BOOL   DC_V_Config.ShortDay
  659.  *        BOOL   DC_V_Config.ShowSecs
  660.  *        UWORD  DC_V_Config.DateFormat
  661.  *        STRING DC_V_Config.LocaleDateFormat
  662.  *        UWORD  DC_V_Config.ScreenSelection
  663.  *        STRING DC_V_Config.ScreenPatternStr
  664.  *               
  665.  */
  666.  
  667. APTR
  668.    ReadDigitalClock(UBYTE *chunkbuf, ULONG size)
  669. {
  670.    register UWORD *puword=(UWORD *)chunkbuf;
  671.    register LONG  *plong;
  672.    register UBYTE *pstr;
  673.    char *str;
  674.    
  675.    DC_V_Config.State = *puword++;
  676.    DC_V_Config.Offset = *puword++;
  677.    plong = (LONG *)puword;
  678.    
  679.    DC_V_Config.Interval = *plong++;
  680.    puword = (UWORD *)plong;
  681.    
  682.    DC_V_Config.ShowDate   = (BOOL) *puword++;
  683.    DC_V_Config.ShowDay    = (BOOL) *puword++;
  684.    DC_V_Config.ShortDay   = (BOOL) *puword++;
  685.    DC_V_Config.ShowSecs   = (BOOL) *puword++;
  686.    DC_V_Config.DateFormat = (BOOL) *puword++;
  687.    pstr = (UBYTE *)puword;
  688.    
  689.    str = DupStr(pstr);
  690.    if (DC_V_Config.LocaleDateFormat)
  691.    {
  692.       FreeVec(DC_V_Config.LocaleDateFormat);
  693.    }
  694.    DC_V_Config.LocaleDateFormat = str;
  695.    pstr += strlen(str)+1;
  696.    
  697.    puword = (UWORD *)WORD_ALIGN(pstr);
  698.    
  699.    DC_V_Config.ScreenSelection = *puword++;
  700.    pstr = (UBYTE *)puword;
  701.    
  702.    strncpy(DC_V_Config.ScreenPatternData.patstr, pstr, PATLEN);
  703.    DC_V_Config.ScreenPatternData.patstr[PATLEN] = '\0';
  704.    pstr += strlen(pstr)+1;
  705.    
  706. #ifndef PREFS
  707.    if (DC_F_Init() != 0)
  708.       return "Init of clock failed";
  709. #endif 
  710.    if ((pstr-chunkbuf) == size)
  711.       return 0L;          /* Reading Ok */
  712.    
  713.    return Reading_chunk_ERR;
  714. }
  715.  
  716. #endif /* not CONV */
  717.  
  718. #if defined(PREFS) || defined(CONV)
  719.  
  720. APTR
  721.    WriteDigitalClock(struct IFFHandle *iff, UBYTE *chunkbuf)
  722. {
  723.    register UWORD *puword=(UWORD *)chunkbuf;
  724.    register LONG  *plong;
  725.    register UBYTE *pstr;
  726.    ULONG    size;
  727.    
  728.    *puword++ = DC_V_Config.State;
  729.    *puword++ = DC_V_Config.Offset;
  730.    plong = (LONG *)puword;
  731.    
  732.    *plong++ = DC_V_Config.Interval;
  733.    puword = (UWORD *)plong;
  734.    
  735.    *puword++ = DC_V_Config.ShowDate;
  736.    *puword++ = DC_V_Config.ShowDay;
  737.    *puword++ = DC_V_Config.ShortDay;
  738.    *puword++ = DC_V_Config.ShowSecs;
  739.    *puword++ = DC_V_Config.DateFormat;
  740.    pstr = (UBYTE *)puword;
  741.    
  742.    strcpy(pstr, DC_V_Config.LocaleDateFormat);
  743.    pstr += strlen(pstr)+1;
  744.    /* Take care of non word aligned addresses for 68000 */
  745.    puword = (UWORD *)WORD_ALIGN(pstr);
  746.    
  747.    *puword++ = DC_V_Config.ScreenSelection;
  748.    pstr = (UBYTE *)puword;
  749.    
  750.    strcpy(pstr, DC_V_Config.ScreenPatternData.patstr);
  751.    pstr += strlen(pstr)+1;
  752.    
  753.    /* Write Chunk */
  754.    size = pstr - chunkbuf;
  755.    if ((PushChunk(iff, 0, ID_YKDC, size)) ||
  756.        (WriteChunkBytes(iff, chunkbuf, size) != size) ||
  757.        (PopChunk(iff)))
  758.       return Writing_prefs_file_ERR;
  759.    
  760.    /* All OK. */
  761.    return 0L;
  762. }
  763. #endif /* PREFS || CONV */
  764.  
  765. #ifdef STAND_ALONE
  766.  
  767. /**************************************************************************/ 
  768. /**************************************************************************/ 
  769. /* Below are some functions to test DigitalClock as a stand alone program */
  770. /**************************************************************************/ 
  771. /**************************************************************************/ 
  772.  
  773.  
  774. #include <graphics/videocontrol.h>
  775.  
  776.  
  777. struct MsgPort  *broker_mp;
  778. CxObj           *broker;
  779.  
  780. static struct NewBroker newbroker =
  781. {
  782.    NB_VERSION,
  783.    "DigitalClock",
  784.    "DigitalClock",
  785.    "Displays clock in screen titlebar",
  786.    NBU_UNIQUE|NBU_NOTIFY,
  787.    0,
  788.    0,
  789.    0,
  790.    0
  791.    };
  792.  
  793.  
  794. int 
  795.    main(void)
  796. {
  797.    int CXSig;
  798.    long sig;
  799.    CxMsg *CXMsg;
  800.    
  801.    
  802.    /* Open needed libraries */
  803.    DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37);
  804.    GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37);
  805.    IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37);
  806.    UtilityBase = OpenLibrary("utility.library",37);
  807.    CxBase = OpenLibrary("commodities.library",37);
  808.    LocaleBase = OpenLibrary("locale.library",38);
  809.    
  810.    if (!(DOSBase && GfxBase && IntuitionBase && UtilityBase && CxBase))
  811.       /* didn't open */
  812.       goto cleanup;
  813.    
  814.    if (LocaleBase)
  815.       locale = OpenLocale(NULL);
  816.    
  817.    newbroker.nb_Pri = 0;
  818.    
  819.    if (!(broker_mp = CreateMsgPort()))
  820.       goto cleanup;
  821.    
  822.    CXSig   = 1L << broker_mp->mp_SigBit;
  823.    
  824.    newbroker.nb_Port = broker_mp;
  825.    
  826.    if (!(broker = CxBroker(&newbroker,NULL)))
  827.       goto cleanup;
  828.    
  829.    ActivateCxObj(broker,1L);
  830.    
  831.    if (DC_F_Init())
  832.       goto cleanup;
  833.    
  834.    /* Setup done */
  835.    
  836. {
  837.    BOOL Abort = FALSE;
  838.    
  839.    DC_F_EnableClock();
  840.    
  841.    while(!Abort)
  842.    {
  843.       sig = Wait(CXSig|DC_V_TimerSig|SIGBREAKF_CTRL_C);
  844.       
  845.       DC_F_ProcessMsg(sig);
  846.       
  847.       while(CXMsg = (CxMsg *)GetMsg(broker_mp))
  848.       {
  849.          const int msgid = CxMsgID(CXMsg);
  850.          const int msgtype = CxMsgType(CXMsg);
  851.          
  852.          ReplyMsg((struct Message *)CXMsg);
  853.          
  854.          if (msgtype == CXM_COMMAND)
  855.             switch(msgid)
  856.             {
  857.             case CXCMD_DISABLE:
  858.                DC_F_DisableClock();
  859.                ActivateCxObj(broker, 0);
  860.                break;
  861.                
  862.             case CXCMD_ENABLE:
  863.                DC_F_EnableClock();
  864.                ActivateCxObj(broker, 1);
  865.                break;
  866.                
  867.             case CXCMD_KILL:
  868.             case CXCMD_UNIQUE:
  869.                Abort = TRUE;
  870.             }
  871.       }
  872.       
  873.       if (sig & SIGBREAKF_CTRL_C) 
  874.       {
  875.          Abort = TRUE;
  876.       }
  877.    }
  878. }
  879.  
  880.  cleanup:
  881.    DC_F_CleanUp();
  882.  
  883.  
  884. /* Commodity stuff */
  885. if (broker)
  886. {
  887.    DeleteCxObj(broker);
  888.    while(CXMsg = (CxMsg *)GetMsg(broker_mp))
  889.       ReplyMsg((struct Message *)CXMsg);
  890. }
  891. if (broker_mp) DeleteMsgPort(broker_mp);
  892.  
  893. CloseLocale(locale);
  894. CloseLibrary(LocaleBase);
  895. CloseLibrary(IconBase);
  896. CloseLibrary(UtilityBase);
  897. CloseLibrary(CxBase);
  898. CloseLibrary((struct Library *)IntuitionBase);
  899. CloseLibrary((struct Library *)GfxBase);
  900. CloseLibrary((struct Library *)DOSBase);
  901.  
  902. return 0;
  903. }
  904.  
  905. void __regargs
  906.    GetScreenBox(struct Screen *s,
  907.    struct IBox *box,
  908.    UWORD        bar)
  909. {
  910.    struct ViewPortExtra *vpe;
  911.    struct TagItem  vpe_tags[2];
  912.    
  913.    vpe_tags[0].ti_Data = NULL;
  914.    vpe_tags[0].ti_Tag = VTAG_VIEWPORTEXTRA_GET;
  915.    vpe_tags[1].ti_Tag = TAG_DONE;
  916.    
  917.    VideoControl(s->ViewPort.ColorMap, vpe_tags);
  918.    
  919.    if (vpe = (struct ViewPortExtra *)vpe_tags[0].ti_Data)
  920.    {
  921.       
  922.       
  923.       /*
  924.        * Size of the visible  part of the screen
  925.        * Is there an easier way to do it ?
  926.        */
  927.       box->Left = vpe->DisplayClip.MinX;
  928.       box->Top = vpe->DisplayClip.MinY;
  929.       box->Width = vpe->DisplayClip.MaxX - box->Left + 1;
  930.       box->Height = vpe->DisplayClip.MaxY - box->Top + 1;
  931.       
  932.       if (s->LeftEdge < 0)
  933.          box->Left = -s->LeftEdge;
  934.       else
  935.          box->Left = 0;
  936.       if (s->TopEdge < 0)
  937.          box->Top = -s->TopEdge;
  938.       else
  939.          box->Top = 0;
  940.       
  941.    } 
  942.    else
  943.       
  944.    {
  945.       box->Left = 0;
  946.       box->Top = 0;
  947.       box->Width = s->Width;
  948.       box->Height = s->Height;
  949.    }
  950.    
  951.    if (bar)
  952.    {
  953.       if (box->Top <= s->BarHeight)
  954.       {
  955.          int l = s->BarHeight + 1;
  956.          
  957.          box->Height -= (l - box->Top);
  958.          box->Top = l;
  959.       }
  960.    }
  961. }
  962.  
  963. /* parse pattern, report errors */
  964. __regargs BOOL
  965.    InitPattern(char *newpatstr, PatternData *pdata)
  966. {
  967.    char *patstr = newpatstr ? newpatstr : pdata->patstr;
  968.    char *pat;
  969.    LONG len;
  970.    
  971.    if (pat = AllocVec(len = strlen(patstr)*3+10, MEMF_CLEAR))
  972.    {
  973.       if (ParsePattern(patstr, pat, len) != -1)
  974.       {
  975.          if (newpatstr) strncpy(pdata->patstr, newpatstr, PATLEN);
  976.          if (pdata->pat) FreeVec(pdata->pat); 
  977.          pdata->pat = pat;
  978.          return TRUE;
  979.       }
  980.       
  981.       FreeVec(pat);
  982.    }
  983.    
  984.    return FALSE;
  985. }
  986.  
  987. #endif
  988.  
  989.